package com.alibaba.otter.manager.web.service;

import com.alibaba.otter.manager.biz.config.pipeline.PipelineService;
import com.alibaba.otter.manager.biz.statistics.stage.ProcessStatService;
import com.alibaba.otter.manager.web.dto.StageStatDTO;
import com.alibaba.otter.shared.arbitrate.ArbitrateViewService;
import com.alibaba.otter.shared.arbitrate.impl.manage.ChannelArbitrateEvent;
import com.alibaba.otter.shared.arbitrate.model.MainStemEventData;
import com.alibaba.otter.shared.arbitrate.model.PositionEventData;
import com.alibaba.otter.shared.common.model.config.channel.ChannelStatus;
import com.alibaba.otter.shared.common.model.config.pipeline.Pipeline;
import com.alibaba.otter.shared.common.model.statistics.stage.ProcessStat;
import org.springframework.stereotype.Service;

import java.util.Date;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

@Service
public class StageStatAggService {

    private final PipelineService pipelineService;

    private final ProcessStatService processStatService;

    private final ArbitrateViewService arbitrateViewService;

    private final ChannelArbitrateEvent channelArbitrateEvent;

    public StageStatAggService(PipelineService pipelineService,
                               ProcessStatService processStatService,
                               ArbitrateViewService arbitrateViewService,
                               ChannelArbitrateEvent channelArbitrateEvent) {
        this.pipelineService = pipelineService;
        this.processStatService = processStatService;
        this.arbitrateViewService = arbitrateViewService;
        this.channelArbitrateEvent = channelArbitrateEvent;
    }

    public StageStatDTO stageStat(Long pipelineId) {

        Pipeline pipeline = pipelineService.findById(pipelineId);
        List<ProcessStat> processStats = processStatService.listRealtimeProcessStat(pipelineId);


        Long stageStart = 0L;
        Long stageEnd = new Date().getTime();
        long interval = 0L;
        double offset = 0L;
        // 找出最先开始的process的select阶段的开始时间作为起始时间
        if (!processStats.isEmpty()) {
            if (!processStats.get(0).getStageStats().isEmpty()) {
                stageStart = processStats.get(0).getStageStats().get(0).getStartTime();
            }
        }

        // 动态计算每个阶段的长度比例
        if (stageStart > 0) {
            interval = stageEnd - stageStart;
        }
        if (interval > 0) {
            offset = 800.0 / interval;
        }

        // 计算每个process当前任务所做的时间总和
        Map<Long, Long> processTime = new HashMap<>();
        for (ProcessStat processStat : processStats) {
            long timeout = 0L;
            if (!processStat.getStageStats().isEmpty()) {
                timeout = stageEnd - processStat.getStageStats().get(0).getStartTime();
            }
            processTime.put(processStat.getProcessId(), timeout);
        }

        // 获取下mainstem状态信息
        MainStemEventData mainstemData = arbitrateViewService.mainstemData(pipeline.getChannelId(), pipelineId);

        PositionEventData positionData = arbitrateViewService.getCanalCursor(pipeline.getParameters().getDestinationName(),
                pipeline.getParameters().getMainstemClientId());

        ChannelStatus status = channelArbitrateEvent.status(pipeline.getChannelId());

        StageStatDTO stageStatDTO = new StageStatDTO();
        stageStatDTO.setPipeline(pipeline);
        stageStatDTO.setPipelineId(pipelineId);
        stageStatDTO.setProcessStats(processStats);
        stageStatDTO.setOffset(offset);
        stageStatDTO.setStageStart(stageStart);
        stageStatDTO.setStageEnd(stageEnd);
        stageStatDTO.setProcessTime(processTime);
        stageStatDTO.setMainstemData(mainstemData);
        stageStatDTO.setPositionData(positionData);
        stageStatDTO.setChannelStatus(status);

        return stageStatDTO;
    }
}
